package com.cabal.common.util.baidu;

import com.cabal.common.util.TmsHttpClientManager;
import com.cabal.common.util.CabalJsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 访问百度地图的工具类, 参见: http://developer.baidu.com/map/index.php?title=webapi/guide/webservice-placeapi
 *					  http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-placeapi
 * 
 * @author lizhongwen
 */
@Slf4j
public class BaiduApiUtils {
	
	// 3ZblpC0ZMvnqUxD0l8CaqsjU
	// A01450a82424c8d995e3ae3ceaf96c40
	// LPDdjSjva5QNAV0VULjUtR9c
	private static String API_KEY = "LPDdjSjva5QNAV0VULjUtR9c";
	
	private static final String API_KEY_BAK = "3ZblpC0ZMvnqUxD0l8CaqsjU";
	
	private static final String GEOCODING_API="http://api.map.baidu.com/geocoder/v2/";
	
	private static final String POI_SEARCH = "http://api.map.baidu.com/place/v2/search";

	private static final String POI_SEARCH_DETAIL = "http://api.map.baidu.com/place/v2/detail";
	
	private static final String IP_LOCATION_API="http://api.map.baidu.com/location/ip";
	
	private static final String CHARSET = "UTF-8";
	
	private static final String PLACE_SUGGESTION_API = "http://api.map.baidu.com/place/v2/suggestion";

	private static final String OCR_API = "http://apis.baidu.com/apistore/idlocr/ocr";
	
	private static final String POI_SEARCH_ADDRESS = "http://api.map.baidu.com/geocoder?address=%s&output=json&key=%s";


	public static BaiduAddress findBaiduAddressByAddress(String address) {
		String url = null;
		try {
			url = String .format(POI_SEARCH_ADDRESS, URLEncoder.encode(address, "UTF-8"), API_KEY);
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		} 
		HttpGet get = null;
		HttpClient client = null;
		BaiduAddress baiduAddress = null;
		
		try {
			client =  HttpClientBuilder.create().build();
			get = TmsHttpClientManager.getGetMethod(url);
			HttpResponse response = client.execute(get);
			String json = EntityUtils.toString(response.getEntity(), CHARSET);
			if (json.indexOf("location") < 0) {
				log.error("fail to get coordinate for address :" + address);
				return null;
			}

			Map properties = CabalJsonUtil.json2map(json);
			if(!"OK".equals(properties.get("status"))) {
				log.error("fail to get coordinate for address :" + address);
				return null;
			}
			Map<String, Object> item = (Map<String, Object>) properties.get("result");
			Map<String, Object> location = (Map<String, Object>) item.get("location");
			baiduAddress = new BaiduAddress(); 
			baiduAddress.setLatitude((Double) location.get("lat"));
			baiduAddress.setLongitude((Double) location.get("lng"));

			baiduAddress = findAddressByCoordinate(baiduAddress);
		} catch (Exception e) {
			log.error("fail to get coordinate for address :" + address,e);
			API_KEY = API_KEY_BAK;
		}
		return baiduAddress;
	}

	public static BaiduAddress findAddressByCoordinate(BaiduAddress baiduAddress){
		double latitude = baiduAddress.getLatitude();
		double longitude = baiduAddress.getLongitude();
		String url = GEOCODING_API+"?output=json&pois=0&ak="+API_KEY+"&location="+latitude+","+longitude;
		HttpGet get = null;
		HttpClient client = null;
		try {
			client =  HttpClientBuilder.create().build();
			get = TmsHttpClientManager.getGetMethod(url);
			HttpResponse response = client.execute(get);
			String json = EntityUtils.toString(response.getEntity(), CHARSET);
			if (json.indexOf("addressComponent")<0) {
				log.error("fail to get coordinate for longitude:" + longitude +" and latitude :" + latitude);
				return baiduAddress;
			}

			Map properties = CabalJsonUtil.json2map(json);
			int status = (int) properties.get("status");
			if (status!=0) {
				log.error("fail to get coordinate for longitude:" + longitude +" and latitude :" + latitude);
				return baiduAddress;
			}
			Map result= (Map) properties.get("result");
			if (result!=null && result.get("addressComponent")!=null) {
				Map addressComponents= (Map) result.get("addressComponent");
				baiduAddress = new BaiduAddress();
				baiduAddress.setProvince((String)addressComponents.get("province"));
				baiduAddress.setCity((String)addressComponents.get("city"));
				baiduAddress.setDistrict((String)addressComponents.get("district"));
				baiduAddress.setStreet((String)addressComponents.get("street"));
				baiduAddress.setStreetNumber((String)addressComponents.get("street_number"));
				baiduAddress.setAddress((String)properties.get("formatted_address"));
				//经度值
				baiduAddress.setLongitude(longitude);
				//纬度值
				baiduAddress.setLatitude(latitude);
			}
		} catch (Exception e) {
			log.error("fail to get coordinate for longitude:" + longitude +" and latitude :" + latitude,e);
			API_KEY = API_KEY_BAK;
		}
		return baiduAddress;
	}

	/**
	 * 正则表达式解析地址
	 *
	 * @param address
	 * @return
	 */
	public static List<Map<String,String>> addressResolution(String address){
		String regex="(?<province>[^省]+省|.+自治区)(?<city>[^自治州]+自治州|[^市]+市|[^盟]+盟|[^地区]+地区|.+区划)(?<county>[^市]+市|[^县]+县|[^旗]+旗|.+区)?(?<town>[^区]+区|.+镇)?(?<village>.*)";
		Matcher m= Pattern.compile(regex).matcher(address);
		String province=null,city=null,county=null,town=null,village=null;
		List<Map<String,String>> table=new ArrayList<Map<String,String>>();
		Map<String,String> row=null;
		while(m.find()){
			row=new LinkedHashMap<String,String>();
			province=m.group("province");
			row.put("province", province==null?"":province.trim());
			city=m.group("city");
			row.put("city", city==null?"":city.trim());
			county=m.group("county");
			row.put("county", county==null?"":county.trim());
			town=m.group("town");
			row.put("town", town==null?"":town.trim());
			village=m.group("village");
			row.put("village", village==null?"":village.trim());
			table.add(row);
		}
		return table;
	}

	

	public static void main(String[] args) {
		BaiduAddress address = findBaiduAddressByAddress("广东揭阳公司");
		System.out.println(address.getProvince());
		System.out.println(address.getCity());
		System.out.println(address.getDistrict());
		System.out.println(address.getStreet() + address.getStreetNumber());

	}


}
